package com.invoicerecognition.backend.service.impl.Invoice;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.invoicerecognition.backend.mapper.InvoiceMapper;
import com.invoicerecognition.backend.mapper.StudentMapper;
import com.invoicerecognition.backend.mapper.TeacherMapper;
import com.invoicerecognition.backend.model.dto.Invoice;
import com.invoicerecognition.backend.model.dto.Student;
import com.invoicerecognition.backend.model.dto.Teacher;
import com.invoicerecognition.backend.model.dto.User;
import com.invoicerecognition.backend.service.Invoice.GetInvoiceSearchResultService;
import com.invoicerecognition.backend.service.impl.utils.UserDetailsImpl;
import com.invoicerecognition.backend.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

@Service
public class GetInvoiceSearchResultServiceImpl implements GetInvoiceSearchResultService {
    @Autowired
    private InvoiceMapper invoiceMapper;

    @Autowired
    private TeacherMapper teacherMapper;

    @Autowired
    private StudentMapper studentMapper;

    @Override
    public JSONObject getSearchResult(Map<String, String> data) {

        String selectedOption = data.get("selectedOption");
        String searchQuery = data.get("searchQuery");
        String selectedMatching = data.get("selectedMatching");
        String selectedObject = data.get("selectedObject");
        int page = Integer.parseInt(data.get("page"));

        JSONObject resp = new JSONObject();

        if ("选择搜索方式".equals(selectedOption)) {
            resp.put("error_message", "请选择搜索方式");
            return resp;
        }

//        searchQuery = searchQuery.trim();
        if (searchQuery.length() == 0) {
            resp.put("error_message", "搜索内容不能为空");
            return resp;
        }

        UsernamePasswordAuthenticationToken authenticationToken =
                (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        UserDetailsImpl loginUser = (UserDetailsImpl) authenticationToken.getPrincipal();
        User user = loginUser.getUser();

        // 实现分页，IPage是mybatisplus的配置
        IPage<Invoice> recordIPage = new Page<>(page, 10);   // 第一个参数是第几页，第二个参数是每一页里面有多少个项目
        QueryWrapper<Invoice> queryWrapper =new QueryWrapper<>();

        if ("student".equals(selectedObject)) {     // 搜索学生的发票
            Integer userId = user.getId();
            QueryWrapper<Teacher> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("user_id", userId);
            Teacher teacher = teacherMapper.selectOne(queryWrapper1);
            // 老师还没填写个人信息
            if (teacher == null) {
                resp.put("error_message", "error");
                return resp;
            }
            else {
                Set<String> studentUserIds = teacher.getStudents();
                // 老师还没有添加学生
                if (studentUserIds.isEmpty()) {
                    resp.put("error_message", "error");
                    return resp;
                }
                else {
                    // 使用 Iterator 来遍历 Set，因为 Set 不保证元素的顺序
                    final int size = studentUserIds.size();
                    Iterator<String> iterator = studentUserIds.iterator();
                    final AtomicInteger index = new AtomicInteger(0);

                    queryWrapper.and(wrapper -> {
                        while (iterator.hasNext()) {
                            String studentUserId = iterator.next();
                            int currentIndex = index.getAndIncrement();  // 获取当前元素的索引并自增

                            if (currentIndex == size - 1) {
                                // 如果是最后一个元素
                                wrapper.eq("user_id", Integer.parseInt(studentUserId));
                            } else {
                                // 不是最后一个元素，添加 or()
                                wrapper.eq("user_id", Integer.parseInt(studentUserId)).or();
                            }
                        }
                    });

                }
            }
        }
        else {      // 搜索自己的发票
            queryWrapper.eq("user_id", user.getId());
        }

        if ("exactMatching".equals(selectedMatching)) {
            if ("createtime".equals(selectedOption)) {
                if (!DateUtils.isValidDate(searchQuery)) {
                    resp.put("error_message", "日期不合法");
                    return resp;
                }
                queryWrapper.orderByDesc("id")
                        .apply("DATE(createtime) = {0}", searchQuery);
            }
            else {
                queryWrapper.orderByDesc("id")
                        .eq(selectedOption, searchQuery);
            }
        }
        else {
            if ("createtime".equals(selectedOption)) {
                queryWrapper.orderByDesc("id")
                        .and(wrapper -> wrapper
                                .apply("DATE_FORMAT(createtime, '%Y-%m') LIKE {0}", searchQuery)  // 支持 'YYYY-MM' 格式
                                .or()  // 使用 OR 连接，支持不同日期格式
                                .apply("DATE_FORMAT(createtime, '%Y-%m-%d') LIKE {0}", searchQuery)  // 支持 'YYYY-MM-DD' 格式
                                .or()  // 使用 OR 连接，支持不同日期格式
                                .apply("DATE_FORMAT(createtime, '%m') LIKE {0}", searchQuery)  // 支持 'MM' 格式
                                .or()  // 使用 OR 连接，支持不同日期格式
                                .apply("DATE_FORMAT(createtime, '%Y') LIKE {0}", searchQuery)  // 支持 'YYYY' 格式
                                .or()  // 使用 OR 连接，支持不同日期格式
                                .apply("DATE_FORMAT(createtime, '%d') LIKE {0}", searchQuery)  // 支持 'DD' 格式
                                .or()  // 使用 OR 连接，支持不同日期格式
                                .apply("DATE_FORMAT(createtime, '%m-%d') LIKE {0}", searchQuery)  // 支持 'MM-DD' 格式
                        );
            }
            else {
                queryWrapper.orderByDesc("id")
                        .like(selectedOption, searchQuery);
            }
        }
        List<Invoice> records = invoiceMapper.selectPage(recordIPage, queryWrapper).getRecords();
        List<Student> studentInfo = new ArrayList<>();

        if ("student".equals(selectedObject)) {
            for (Invoice record: records) {
                int studentUserId = record.getUserId();
                QueryWrapper<Student> queryWrapperInfo = new QueryWrapper<>();
                queryWrapperInfo.eq("user_id", studentUserId);
                Student student = studentMapper.selectOne(queryWrapperInfo);
                studentInfo.add(student);
            }
        }

        resp.put("error_message", "success");
        resp.put("records", records);
        resp.put("records_count", invoiceMapper.selectCount(queryWrapper));
        resp.put("student_info", studentInfo);

        return resp;
    }
}
